/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package util.file.apache_commons;

import util.file.OperacionSubida;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.PageContext;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import util.exception.ExceptionUtil;
import util.file.FileUtil;
import util.file.Archivo;
/**
 *
 * @author Rdelacruz
 */
public class FileUploadUtil {
    
    //http://www.tutorialspoint.com/jsp/jsp_file_uploading.htm
    //PageContext: http://docs.oracle.com/javaee/1.4/api/javax/servlet/jsp/PageContext.html    
    /*
    FORMULARIO
    <form action="UploadServlet" method="post" enctype="multipart/form-data">
        <input type="file" name="file" size="50" /> <br />        
        <input type="submit" value="Upload File" />
    </form> 
    */
    public static void subirArchivosEnJSP(PageContext pageContext) throws Exception { 
        HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
        HttpServletResponse response = (HttpServletResponse) pageContext.getResponse();
        
        /*
        WEB.XML:
        <web-app>
            ....
            <context-param> 
                <description>Location to store uploaded file</description> 
                <param-name>file-upload</param-name> 
                <param-value>
                     c:\apache-tomcat-5.5.29\webapps\data\
                 </param-value> 
            </context-param>
            ....
        </web-app>
        */
        ServletContext context = pageContext.getServletContext();//referencia al web.xml
        String filePath = context.getInitParameter("file-upload");
        
        List<OperacionSubida> lista = subirArchivos(request, filePath, "C:\\temp", true, false);
        
        PrintWriter out = response.getWriter(); 
        if(lista.isEmpty()) {
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet upload</title>");  
            out.println("</head>");
            out.println("<body>");
            out.println("<p>Ningun archivo fue subido (No file uploaded)</p>"); 
            out.println("</body>");
            out.println("</html>");
        }
        else {
            out.println("<html>");
            out.println("<head>");
            out.println("<title>JSP File upload</title>");  
            out.println("</head>");
            out.println("<body>");
            for(OperacionSubida op : lista) {
                out.println("Archivo subido: " + op.getArchivo().getNombre() + "<br>");
            }
            out.println("</body>");
            out.println("</html>");
        }
    }
    
    
    //Retorna los archivos subidos
    public static List<OperacionSubida> subirArchivos(
            HttpServletRequest request, 
            String rutaUpload, 
            String rutaUploadMaxMemSize, 
            boolean crearDirectorioSiNoExiste,
            boolean subirComoTemporal
    ) 
            
            throws FileUploadException, Exception {
        //rutaUpload = rutaUpload;
        //rutaUpload = rutaUpload.replace("\\", "/");
        //rutaUploadMaxMemSize = rutaUploadMaxMemSize.replace("\\", "/");
                
        //REVISANDO SI EXISTE DIRECTORIO
        FileUtil.crearDirectorioSiNoExiste(rutaUpload, false);
        FileUtil.crearDirectorioSiNoExiste(rutaUploadMaxMemSize, false);
        
        File file ;
        int maxFileSize = 5000 * 1024;//5MB
        int maxMemSize = 5000 * 1024;//5MB
        String filePath = rutaUpload;
        
        // Verify the content type        
        String contentType = request.getContentType();
        if(contentType!=null) {
            List<OperacionSubida> operaciones = new ArrayList<OperacionSubida>();
            if ((contentType.indexOf("multipart/form-data") >= 0)) {

                DiskFileItemFactory factory = new DiskFileItemFactory();
                // maximum size that will be stored in memory
                factory.setSizeThreshold(maxMemSize);
                // Location to save data that is larger than maxMemSize.
                factory.setRepository(new File(rutaUploadMaxMemSize));

                // Create a new file upload handler
                ServletFileUpload upload = new ServletFileUpload(factory);
                // maximum file size to be uploaded.
                upload.setSizeMax( maxFileSize );             
                
                // Parse the request to get file items.
                List fileItems = upload.parseRequest(request);//FileUploadException

                // Process the uploaded file items
                Iterator i = fileItems.iterator();

                while ( i.hasNext () ) {
                                        
                    OperacionSubida op = new OperacionSubida();
                    Friend opFriend = new Friend();
                    op.registrarFriend(opFriend);
                    
                    opFriend.friend.setOk(false); //op.setOk(false);
                    
                    
                    Archivo a = new Archivo();
                                        
                    //NOTA:
                    //Si el flujo llega hasta aqui, entonces se subira 
                    //cada archivo y se cogerá la excepcion, 
                    //para no interrumpir el proceso.
                    //Antes de aqui las excepciones si interrumpen el proceso
                    try {
                        FileItem fi = (FileItem)i.next();
                        if ( !fi.isFormField () ) {
                            // Get the uploaded file parameters
                            String fieldName = fi.getFieldName();
                            
                            String fileName = fi.getName();
                            //En IE: fileName= "C:\directorio\mi_archivo.dat"
                            //En Firefox y Chrome: fileName= "mi_archivo.dat"
                            
                            boolean isInMemory = fi.isInMemory();
                            long sizeInBytes = fi.getSize();

                            // Write the file
                            String filenamefinal;
                            int indice = fileName.lastIndexOf("\\");
                            if( indice >= 0 ){
                                filenamefinal = fileName.substring(indice+1);                                
                            }else{
                                filenamefinal = fileName;
                            }
                            
                            a.setNombre(filenamefinal);
                            a.setTamanho(sizeInBytes);
                            
                            file = new File( filePath, filenamefinal ) ;
                            //a.setUrl(file.getAbsolutePath());
                            a.setUrl(file.getPath());
                            
                            //SUBIENDO EL ARCHIVO
                            if(subirComoTemporal) {
                                File file_temp = util.file.FileUtil.getNonExistingTempFile(file);
                                fi.write( file_temp );
                                
                                Archivo aTemp = new Archivo();
                                aTemp.setNombre(file_temp.getName());
                                aTemp.setUrl(file_temp.getPath());
                                aTemp.setTamanho(sizeInBytes);                                
                                
                                op.setArchivoTemporal(aTemp);
                            }
                            else {
                                fi.write( file );                                
                            }   
                            
                            op.setArchivo(a);                            
                            op.setFecha(new Date());
                                             
                            opFriend.friend.setOk(true);//op.setOk(true);
                        }
                    }
                    catch(Exception ex) {
                        op.setMensajeError("No se pudo subir el archivo '"+a.getNombre()+"'\n "+ExceptionUtil.getStackTrace(ex));
                    }
                    finally {
                        //Solamente se registrarán los archivos con nombre, sean subidos o no
                        //if(a.getNombre()!=null)
                        //    archivosSubidos.add(a);
                        
                        //Se registra el archivo subido
                        operaciones.add(op);
                    }
                }                    
            }            
            return operaciones;
        } else {
            //Lanza una excepcion que muestra un ejemplo de un formulario para subir un archivo
            StringBuilder sb = new StringBuilder();
            sb.append("Mal uso de este método. Debe enviar el request con un formulario con la siguiente forma:\n\n");
            sb.append("<form action='UploadServlet' method='post' enctype='multipart/form-data'>\n");
            sb.append("<input type=\"file\" name=\"file\" size=\"50\" /> <br />\n");
            sb.append("<input type=\"submit\" value=\"Upload File\" />\n");
            sb.append("</form>\n");                 
            throw new Exception(sb.toString());
        }        
        //return null;
    }
    
    //Ejemplo completo: formulario.jsp, resultado.jsp, web.xml
    // http://javarevisited.blogspot.com/2013/07/ile-upload-example-in-servlet-and-jsp-java-web-tutorial-example.html#ixzz31tJJxnEv
    /*    
    //FORMULARIO:
    <form action="upload" method="post" enctype="multipart/form-data">
        <input type="file" name="file" />
        <input type="submit" value="upload" />
    </form> 
    */
    public static void subirArchivos_1(HttpServletRequest request, HttpServletResponse response, String rutaUpload) throws ServletException, IOException {
        //final String UPLOAD_DIRECTORY = "C:/uploads";
        //rutaUpload = UPLOAD_DIRECTORY;
        
        //process only if its multipart content
        if(ServletFileUpload.isMultipartContent(request)){
            try {
                List<FileItem> multiparts = new ServletFileUpload(
                                         new DiskFileItemFactory()).parseRequest(request);

                for(FileItem item : multiparts){
                    if(!item.isFormField()){
                        String name = new File(item.getName()).getName();
                        item.write( new File(rutaUpload + File.separator + name));
                    }
                }

                //File uploaded successfully
                request.setAttribute("message", "File Uploaded Successfully");
            } catch (Exception ex) {
                request.setAttribute("message", "File Upload Failed due to " + ex);
            }         
        }else{
            request.setAttribute("message",
                                 "Sorry this Servlet only handles file upload request");
        }    
        request.getRequestDispatcher("/result.jsp").forward(request, response);
    }
    
    

    
}
